package com.rizzo.web.backingbeans.util;

import com.rizzo.back.exception.ApplicationException;
import com.rizzo.web.delegator.UtilDelegator;
import com.rizzo.web.security.Function;
import com.rizzo.web.security.Role;
import com.rizzo.web.security.RolesService;
import com.rizzo.web.util.LocaleEnum;
import com.rizzo.web.util.SecurityUtil;
import org.springframework.web.servlet.LocaleResolver;

import javax.faces.context.FacesContext;
import javax.servlet.http.HttpServletRequest;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

/**
 * Utility BackingBean responsible for showing general things on the views.
 *
 * @author Jan lievens
 */
public class UtilBackingBean implements Serializable {

    /**
     * Field utilDelegator
     */
    private transient UtilDelegator utilDelegator;

    /**
     * Field rolesService
     */
    private transient RolesService rolesService;

    /**
     * Field localeResolver
     */
    private LocaleResolver localeResolver;

    /**
     * Field userSelectedLocale
     */
    private String userSelectedLocale;


    /**
     * Method getLocale returns the locale of this UtilBackingBean object.
     *
     * @return the locale (type Locale) of this UtilBackingBean object.
     */
    public Locale getLocale() {
        HttpServletRequest httpServletRequest = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
        return this.localeResolver.resolveLocale(httpServletRequest);
    }

    /**
     * Method getPossibleLocales returns the possibleLocales of this UtilBackingBean object.
     *
     * @return the possibleLocales (type List<LocaleEnum>) of this UtilBackingBean object.
     */
    public List<LocaleEnum> getPossibleLocales() {
        List<String> possibleLocaleStr = null;
        try {
            possibleLocaleStr = this.utilDelegator.getPossibleLocales();
        } catch (ApplicationException e) {
            // TODO e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        List<LocaleEnum> possibleLocales = new ArrayList<LocaleEnum>();
        if (possibleLocaleStr != null) {
            for (String locale : possibleLocaleStr) {
                possibleLocales.add(LocaleEnum.valueOf(locale.toUpperCase()));
            }
        }
        return possibleLocales;
    }

    /**
     * Method getMetaDescription returns the metaDescription of this UtilBackingBean object.
     *
     * @return the metaDescription (type String) of this UtilBackingBean object.
     */
    public String getMetaDescription() {
        String metaDescription = null;
        try {
            metaDescription = this.utilDelegator.getMetaDescription();
        } catch (ApplicationException e) {
            //MessageUtil.populateMessages(); TODO
        }
        return metaDescription;
    }

    /**
     * Method getMetaKeywords returns the metaKeywords of this UtilBackingBean object.
     *
     * @return the metaKeywords (type String) of this UtilBackingBean object.
     */
    public String getMetaKeywords() {
        String metaKeywords = null;
        try {
            metaKeywords = this.utilDelegator.getMetaKeywords();
        } catch (ApplicationException e) {
            //MessageUtil.populateMessages(); TODO
        }
        return metaKeywords;
    }

    /**
     * Method getHtmlAdminAddress returns the htmlAdminAddress of this UtilBackingBean object.
     *
     * @return the htmlAdminAddress (type String) of this UtilBackingBean object.
     */
    public String getHtmlAdminAddress() {
        String htmlAdminAddress = null;
        try {
            htmlAdminAddress = this.utilDelegator.getHtmlAdminAddress();
        } catch (ApplicationException e) {
            // TODO e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        }
        return htmlAdminAddress;
    }

    /**
     * Method getMediaLocationUrl returns the mediaLocationUrl of this UtilBackingBean object.
     *
     * @return the mediaLocationUrl (type String) of this UtilBackingBean object.
     */
    public Integer getMaxEntriesPageDatatable() {
        Integer maxEntriesPageDatatable = 25;
        try {
            maxEntriesPageDatatable = this.utilDelegator.getMaxEntriesPageDatatable();
        } catch (ApplicationException e) {
            //e.printStackTrace();  //TODO
        }
        return maxEntriesPageDatatable;
    }

    /**
     * Method getLocaleSelectionVisible returns the localeSelectionVisible of this UtilBackingBean object.
     *
     * @return the localeSelectionVisible (type Boolean) of this UtilBackingBean object.
     */
    public Boolean getLocaleSelectionVisible() {
        Boolean localeSelectionVisible = true;
        Boolean isUserKnown = SecurityUtil.isUserKnown();
        try {
            localeSelectionVisible = this.utilDelegator.getLocaleSelectionVisible();
        } catch (ApplicationException e) {
            //e.printStackTrace();  //TODO
        }
        return (localeSelectionVisible) ? true : isUserKnown;
    }

    /**
     * Returns a list of Function objects by which the navigation-menu is constructed.
     * A user can have multiple roles (so functions can be defined twice). In this method we will filter the duplicates out.
     *
     * @return A List of {@link com.rizzo.web.security.Function}
     */
    public List<Function> getNavigationFunctions() {
        List<Function> functions = new ArrayList<Function>();
        // retrieve the roles from the principal-object
        String[] rolesFromLDAP = SecurityUtil.getRoles();
        // retrieve the possible functions (actions) from the RolesService
        List<Role> roles = this.rolesService.getRolesForNames(rolesFromLDAP);
        // put all the functions from the different roles in the functions of the backingbean
        for (Role role : roles) {
            List<Function> roleFunctions = role.getFunctions();
            for (Function function : roleFunctions) {
                if ("navigation".equals(function.getPanel())) {
                    if (!functions.contains(function)) {
                        functions.add(function);
                    }
                }
            }
        }
        return functions;
    }

    /**
     * Returns a list of Function objects by which the sidePanel-menu is constructed.
     *
     * @return A List of {@link com.rizzo.web.security.Function}.
     */
    public List<Function> getSidePanelFunctions() {
        List<Function> functions = new ArrayList<Function>();
        // retrieve the roles from the principal-object
        String[] rolesFromLDAP = SecurityUtil.getRoles();
        // retrieve the possible functions (actions) from the RolesService
        List<Role> roles = this.rolesService.getRolesForNames(rolesFromLDAP);
        // put all the functions from the different roles in the functions of the backingbean
        for (Role role : roles) {
            List<Function> roleFunctions = role.getFunctions();
            for (Function function : roleFunctions) {
                if ("sidePanel".equals(function.getPanel())) {
                    if (!functions.contains(function)) {
                        functions.add(function);
                    }
                }
            }
        }
        return functions;
    }

    /**
     * Method getUserSelectedLocale returns the userSelectedLocale of this UtilBackingBean object.
     *
     * @return the userSelectedLocale (type String) of this UtilBackingBean object.
     */
    public String getUserSelectedLocale() {
        return userSelectedLocale;
    }

    /**
     * Method setUserSelectedLocale sets the userSelectedLocale of this UtilBackingBean object.
     *
     * @param userSelectedLocale the userSelectedLocale of this UtilBackingBean object.
     */
    public void setUserSelectedLocale(String userSelectedLocale) {
        this.userSelectedLocale = userSelectedLocale;
    }

    /**
     * Method setUtilDelegator sets the utilDelegator of this UtilBackingBean object.
     *
     * @param utilDelegator the utilDelegator of this UtilBackingBean object.
     */
    public void setUtilDelegator(UtilDelegator utilDelegator) {
        this.utilDelegator = utilDelegator;
    }

    /**
     * Method setRolesService sets the rolesService of this UtilBackingBean object.
     *
     * @param rolesService the rolesService of this UtilBackingBean object.
     */
    public void setRolesService(RolesService rolesService) {
        this.rolesService = rolesService;
    }

    /**
     * Method setLocaleResolver sets the localeResolver of this UtilBackingBean object.
     *
     * @param localeResolver the localeResolver of this UtilBackingBean object.
     */
    public void setLocaleResolver(LocaleResolver localeResolver) {
        this.localeResolver = localeResolver;
    }
}
